package example.demo.sync.objecthead;

import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/*
 * 加依赖
 * <dependency>
 *      <groupId>org.openjdk.jol</groupId>
 *      <artifactId>jol-core</artifactId>
 *      <version>0.10</version>
 * </dependency>
 *
 * 关闭延迟开启偏向锁
 *-XX:BiasedLockingStartupDelay=0
 *禁止偏向锁
 *-XX:-UseBiasedLocking
 *启用偏向锁
 *-XX:+UseBiasedLocking
 *
 * 验证偏向锁的markword记录的是线程的id--借助jps+jstack来验证，粘贴jstack的内容到notepad查找main
 * 101无锁偏向与有锁偏向都是101
 * 001 不可偏向
 * 00 轻量锁
 * 10重量
 */
@Slf4j(topic = "rao")
public class SyncLevelUp {
    static final Object lock = new Object();

    static class Student {
        private String name;
        private Integer age;
    }


    public static void main(String[] args) throws InterruptedException {

        Thread main_thread = Thread.currentThread();

        final Object obj = new Object();
        log.info("未计算hashcode--obj==" + ClassLayout.parseInstance(obj).toPrintable());
        synchronized (obj) {
            log.info("main线程==obj" + ClassLayout.parseInstance(obj).toPrintable());
        }
        log.info(Integer.toHexString(obj.hashCode()));
        log.info("计算hashcode--obj==" + ClassLayout.parseInstance(obj).toPrintable());
        synchronized (obj) {
            log.info("main线程==obj" + ClassLayout.parseInstance(obj).toPrintable());
        }

        log.info("无锁" + ClassLayout.parseInstance(lock).toPrintable());
        synchronized (lock) {
            log.info("main线程" + ClassLayout.parseInstance(lock).toPrintable());
            synchronized (lock) {
                log.info("main重入" + ClassLayout.parseInstance(lock).toPrintable());
            }
        }
        synchronized (lock) {
            log.info("main第三次" + ClassLayout.parseInstance(lock).toPrintable());
        }

        TimeUnit.SECONDS.sleep(1);
        new Thread(() -> {
            synchronized (lock) {
                log.info("发生交替AAA" + ClassLayout.parseInstance(lock).toPrintable());
            }
        }, "AAA").start();

        TimeUnit.SECONDS.sleep(1);

        synchronized (lock) {
            log.info("main发生交替" + ClassLayout.parseInstance(lock).toPrintable());
        }

        TimeUnit.SECONDS.sleep(1);

        synchronized (lock) {
            log.info("main发生竞争之前，还是交替--" + ClassLayout.parseInstance(lock).toPrintable());
            new Thread(() -> {
                log.info(Thread.currentThread().getName());
                synchronized (lock) {
                    log.info("BBB发生竞争--" + ClassLayout.parseInstance(lock).toPrintable());
                }
            }, "BBB").start();
            new Thread(() -> {
                log.info(Thread.currentThread().getName());
                synchronized (lock) {
                    log.info("CCC发生竞争--" + ClassLayout.parseInstance(lock).toPrintable());
                }
            }, "ccc").start();
            new Thread(() -> {
                log.info(Thread.currentThread().getName());
                synchronized (lock) {
                    log.info("ddd发生竞争--" + ClassLayout.parseInstance(lock).toPrintable());
                }
            }, "ddd").start();
            TimeUnit.SECONDS.sleep(20);
            log.info("main发生竞争--" + ClassLayout.parseInstance(lock).toPrintable());
        }

        TimeUnit.SECONDS.sleep(3);

        log.info("没人拿锁打印--" + ClassLayout.parseInstance(lock).toPrintable());
        TimeUnit.SECONDS.sleep(1);
        synchronized (lock) {
            log.info("main--" + ClassLayout.parseInstance(lock).toPrintable());
        }
    }
}
